package com.mall.shopping.services.cart;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mall.shopping.ICartService;
import com.mall.shopping.constants.ShoppingRetCode;
import com.mall.shopping.dal.persistence.ItemCatMapper;
import com.mall.shopping.dto.*;
import com.mall.shopping.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * @author: Silence_W
 * @date: 2021-01-23 16:18
 **/

@Slf4j
@Service
@Component
public class ICartServiceImpl implements ICartService {

    @Autowired
    ItemCatMapper itemCatMapper;

    @Autowired
    RedissonClient redissonClient;

    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {

        List<CartProductDto> list = new ArrayList<>();
        List<AddCartResponse> list1 = new ArrayList<>();
        CartListByIdResponse response = new CartListByIdResponse();
        try {
            request.requestCheck();
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            Map<Long, Object> map = redissonClient.getMap(request.getUserId().toString());
            if (map.isEmpty()) {
                response.setCartProductDtos(list);
                return response;
            }

            Set<Map.Entry<Long, Object>> entries = map.entrySet();
            for (Map.Entry<Long, Object> entry : entries) {
                String re = (String) entry.getValue();
                AddCartResponse value = JSONObject.parseObject(re, AddCartResponse.class);
                list1.add(value);
                CartProductDto cartProductDto = convert(value);
                list.add(cartProductDto);
            }
            List<CartProductDto> lists = sortByTime(list1);
            response.setCartProductDtos(lists);
        } catch (Exception e) {
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    private CartProductDto convert(AddCartResponse value) {
        CartProductDto cartProductDto = new CartProductDto();
        cartProductDto.setChecked(value.getChecked().toString());
        cartProductDto.setLimitNum(value.getLimitNum());
        cartProductDto.setProductId(value.getProductId());

        cartProductDto.setProductImg(value.getBigImg());
        cartProductDto.setSalePrice(value.getSalePrice());
        cartProductDto.setProductName(value.getProductName());
        cartProductDto.setProductNum(value.getProductNum());

        return cartProductDto;
    }

    private List<CartProductDto> sortByTime(List<AddCartResponse> list) {
        List<CartProductDto> lists = new ArrayList<>();
        Collections.sort(list);
        for (int i = list.size() - 1; i >= 0; i--) {
            lists.add(convert(list.get(i)));
        }

        return lists;
    }

    @Override
    public AddCartResponse addToCart(AddCartRequest request) {
        AddCartResponse addCartResponse = null;
        try {
            request.requestCheck();

            addCartResponse = itemCatMapper.selectCartById(request.getProductId());



            addCartResponse.setChecked(true);



            RMap<String, Object> map = redissonClient.getMap(request.getUserId().toString());

            if (map.containsKey(request.getProductId().toString())) {

                String string = (String) map.get(request.getProductId().toString());
                AddCartResponse response = JSONObject.parseObject(string, AddCartResponse.class);
                response.setDate(System.currentTimeMillis());
                response.setProductNum(response.getProductNum() +(long) request.getProductNum());
                map.replace(request.getProductId().toString(),JSON.toJSONString(response));
            } else {
                addCartResponse.setProductNum((long) request.getProductNum());
                addCartResponse.setDate(System.currentTimeMillis());
                map.put(request.getProductId().toString(), JSON.toJSONString(addCartResponse));
            }

            addCartResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            addCartResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
        } catch (Exception e) {
            ExceptionProcessorUtils.wrapperHandlerException(addCartResponse, e);
        }
        return addCartResponse;
    }

    //跟新商品~
    @Override
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {
        UpdateCartNumResponse updateCartNumResponse = new UpdateCartNumResponse();
        try {
            request.requestCheck();
            String checked = request.getChecked();
            RMap<String, Object> map = redissonClient.getMap(request.getUserId().toString());
            boolean check = isCheck(checked);

            if (!map.containsKey(request.getProductId().toString())) {
                updateCartNumResponse.setMsg(ShoppingRetCode.DB_EXCEPTION.getMessage());
                updateCartNumResponse.setCode(ShoppingRetCode.DB_EXCEPTION.getCode());
                return updateCartNumResponse;
            }

            String string  = (String) map.get(request.getProductId().toString());
            AddCartResponse response = JSONObject.parseObject(string, AddCartResponse.class);
            response.setProductNum((long) request.getProductNum());
            response.setChecked(check);
            response.setDate(System.currentTimeMillis());
            map.replace(request.getProductId().toString(),JSON.toJSONString(response));

            updateCartNumResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            updateCartNumResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e) {
            ExceptionProcessorUtils.wrapperHandlerException(updateCartNumResponse, e);

        }
        return updateCartNumResponse;
    }

    //全选
    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request) {
        CheckAllItemResponse response = new CheckAllItemResponse();
        try {
            request.requestCheck();
            String checked = request.getChecked();
            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            boolean check = isCheck(checked);

            for (Map.Entry<Object, Object> entry : map.entrySet()) {
                AddCartResponse addCartResponse = JSONObject.parseObject(entry.getValue().toString(), AddCartResponse.class);
                addCartResponse.setChecked(check);
                map.replace(addCartResponse.getProductId().toString(),JSON.toJSONString(addCartResponse));
            }
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e){
            response.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
            response.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            log.error("全选商品出现了错误");
            ExceptionProcessorUtils.wrapperHandlerException(response, e);
        }
        return response;
    }

    //删除商品~
    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request) {
        DeleteCartItemResponse deleteCartItemResponse = new DeleteCartItemResponse();
        try {
            request.requestCheck();
            RMap<Long, Object> map = redissonClient.getMap(request.getUserId().toString());
            if (map.containsKey(request.getItemId().toString())) {
                map.remove(request.getItemId().toString());
                deleteCartItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
                deleteCartItemResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
                return deleteCartItemResponse;
            }
            deleteCartItemResponse.setMsg(ShoppingRetCode.DB_EXCEPTION.getMessage());
            deleteCartItemResponse.setCode(ShoppingRetCode.DB_EXCEPTION.getMessage());
        } catch (Exception e) {
            deleteCartItemResponse.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
            deleteCartItemResponse.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            log.error("删除商品出现了错误");
            ExceptionProcessorUtils.wrapperHandlerException(deleteCartItemResponse, e);
        }

        return deleteCartItemResponse;
    }

    //删除选中的商品
    @Override
    public DeleteCheckedItemResposne deleteCheckedItem(DeleteCheckedItemRequest request) {
        DeleteCheckedItemResposne deleteCheckedItemResposne = new DeleteCheckedItemResposne();
        try {
            request.requestCheck();
            RMap<Object, Object> map = redissonClient.getMap(request.getUserId().toString());
            for (Map.Entry<Object, Object> entry : map.entrySet()) {
                AddCartResponse addCartResponse = JSONObject.parseObject(entry.getValue().toString(), AddCartResponse.class);
                if (addCartResponse.getChecked()){
                    map.remove(entry.getKey());
                }
            }
            deleteCheckedItemResposne.setCode(ShoppingRetCode.SUCCESS.getCode());
            deleteCheckedItemResposne.setMsg(ShoppingRetCode.SUCCESS.getMessage());
        } catch (Exception e){
            deleteCheckedItemResposne.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
            deleteCheckedItemResposne.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            log.error("删除选中的商品出现了错误");
            ExceptionProcessorUtils.wrapperHandlerException(deleteCheckedItemResposne, e);
        }
        return deleteCheckedItemResposne;
    }

    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {

        return null;
    }

    private boolean isCheck(String check) {
        if (check.equals("true")) {
            return true;
        }

        return false;
    }
}
